#ifndef __SmartHomeMonitorServer_H__
#define __SmartHomeMonitorServer_H__

#include "TcpConnection.hpp"
#include "TcpServer.hpp"
#include "Threadpool.hpp"
#include "logger.hpp"
#include "Packet.hpp"
#include "TLV.hpp"
#include "UserLoginSection1.hpp"
#include "UserLoginSection2.hpp"
#include "UserRegisterSection1.hpp"
#include "UserRegisterSection2.hpp"
#include <iostream>
using std::cout;
using std::endl;
//代表的是具体的业务逻辑


//测试的mytask
class Mytask
{
public:
    Mytask( wd::TcpConnectionPtr conn,Packet packet)
    :_conn(conn)
    ,_packet(packet)
    {}

    //该函数的执行要交给线程池中的某一个线程
    //计算线程有多个
    void process()
    {
        cout << "Mytask::process is running" << endl;
        
        //decode
        //测试
        cout << "receive msg: " << _packet._msg;       
        cout << "type:" << _packet.type << endl;
        cout << "length:" << _packet.length << endl;
        //compute


        //encode 封装原始数据
        TLV tlv = Packet::PackettoTLV(_packet); 
        cout <<"send tlv data:" <<  tlv.data;
        cout << "type:" << tlv.type << endl;
        cout << "length:" << tlv.length << endl;
        //将发送任务提交到事件循环中
        _conn->sendInLoop(tlv);
    }

private:
    wd::TcpConnectionPtr _conn;
    Packet               _packet;
};


class SmartHomeMonitorServer
{
public:
    SmartHomeMonitorServer(unsigned short port, 
               const string & ip = "127.0.0.1",
               size_t threadNum = 4,
               size_t queSize = 10)
    :_mylogger(MyLogger::getInstance())
    ,_server(_mylogger,port,ip)
    ,_threadpool(threadNum, queSize)
    {
        using namespace std::placeholders;
        _server.setAllCallbacks(
            std::bind(&SmartHomeMonitorServer::onConnection, this, _1),
            std::bind(&SmartHomeMonitorServer::onMessage, this, _1),
            std::bind(&SmartHomeMonitorServer::onClose, this, _1)
                               );
    }

    void start()
    {
        _threadpool.start();
        _server.start();
    }

    void onConnection(wd::TcpConnectionPtr conn)
    {
        //打印一个新连接的五元组信息
        cout << conn->toString() << " has connected successfully" << endl;
        //这里应该把连接信息记录在日志文件中记录在日志系统中
        _mylogger.serverInfo(conn->toString() + " connected success");
    }

    void onMessage(wd::TcpConnectionPtr conn)
    {
        //进入onMessage函数
        cout << "connection:" << conn->toString() << " onMessage" << endl;
        _mylogger.serverInfo("connection:"+conn->toString()+" onMessage");
        
        //接收一个包
        Packet packet;
        int ret = conn->readPacket(packet);
        //异常处理
        if(-1 == ret){
            _mylogger.serverError("onMessage readPacket error");
        }
        
        //输出Packet的信息
        cout << "onMessage readPacket message:" << packet._msg << endl;
        cout << "Packet.type:" << packet.type << endl;
        cout << "Packet.length:" << packet.length << endl;
        
        if(TASK_LOGIN_SECTION1 == packet.type){
            //执行登录阶段1操作
            UserLoginSection1 task(conn,packet);
            _threadpool.addTask(std::bind(&UserLoginSection1::process, task));
            _mylogger.serverInfo("push TASK_LOGIN_SECTION1 into Threadpool");
        
        }else if(TASK_LOGIN_SECTION2 == packet.type){
           //执行登录阶段2操作
            UserLoginSection2 task(conn,packet);
            _threadpool.addTask(std::bind(&UserLoginSection2::process, task));
            _mylogger.serverInfo("push TASK_LOGIN_SECTION2 into Threadpool");

        }else if(TASK_REGISTER_SECTION1 == packet.type){
            //执行注册阶段1操作
            cout << "----------smhsm 110-----------"<< endl;
            UserRegisterSection1 task(conn,packet);
            _threadpool.addTask(std::bind(&UserRegisterSection1::process, task));
            _mylogger.serverInfo("push TASK_REGISTER_SECTION1 into Threadpool");
        }else if(TASK_REGISTER_SECTION2 == packet.type){
            //执行注册阶段2操作
            UserRegisterSection2 task(conn,packet);
            _threadpool.addTask(std::bind(&UserRegisterSection2::process, task));
            _mylogger.serverInfo("push TASK_REGISTER_SECTION2 into Threadpool");
        }

    }

    void onClose(wd::TcpConnectionPtr conn)
    {
        cout << conn->toString() << " has closed." << endl;
        //记录在日志中
        _mylogger.serverInfo(conn->toString() + " closed");
    }

private:
    MyLogger      &_mylogger;
    wd::TcpServer  _server;
    wd::Threadpool _threadpool;
};

#endif

